﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Collections;
using System.Windows.Media;

namespace LogicalTreeview
{

    public class NamedElement
    {
        public string Name { get; set; }
    }

    public class Child : NamedElement 
    {
         
    } 
    public class Parent  : NamedElement 
    {


        protected List<NamedElement> _children = new List<NamedElement>();
        public List<NamedElement> Children
        {
            get
            {
                return _children;
            }
        } 
    }


    public class TreeWalker
    {
        public static void LogicalWalk ( object o ,  Parent p  ) 
        { 
            
            if ( o is DependencyObject  ) 
            { 
                int count = 0 ; 
                IEnumerable list = LogicalTreeHelper.GetChildren ( o as DependencyObject); 
                foreach ( object o2 in list )   
                {  
                    count++ ;
                    bool skipwalk = false; 
                    Parent p2 = new Parent();
                    if (o2 is FrameworkElement)
                    {
                        string name = (o2 as DependencyObject).GetValue(FrameworkElement.NameProperty) as String; 
                        if ( !string.IsNullOrEmpty ( name )) 
                        { 
                            p2.Name = string.Format("{0}:{1}", o2.GetType().ToString(), name ) ;  
                        } 
                        else
                            p2.Name = o2.GetType().ToString(); 
                    }
                    else
                    {
                        skipwalk  = true; 

                        string name = o2.ToString(); 
                        if ( !string.IsNullOrEmpty ( name ) ) 
                        { 
                            p2.Name = string.Format("{0}:{1}", o2.GetType().ToString(), name ) ;  
                        } 
                        else
                            p2.Name = o2.GetType().ToString(); 
                         
                    }
                    if ( !skipwalk )
                        LogicalWalk (o2, p2);
                    p.Children.Add(p2);   
                }
                if (count == 0)
                {
                    p.Children.Add(new NamedElement() { Name = o.GetType().ToString() });
                }                 
            } 
            else 
            { 
                p.Children.Add ( new NamedElement () 
                        {Name = o.GetType().ToString()}); 
            } 
        }

        public static void VisualWalk(object o, Parent p)
        {

            if (o is DependencyObject)
            {
               
                int itemsinlist = VisualTreeHelper.GetChildrenCount( o as DependencyObject); 
                for (int x = 0; x < itemsinlist; x++)
                {
                    DependencyObject o2 =
                    VisualTreeHelper.GetChild(o as DependencyObject, x);
                    bool skipwalk = false; 
                    Parent p2 = new Parent();
                    skipwalk =
                        VisualTreeHelper.GetChildrenCount(o2)==0; 
                    if (o2 is FrameworkElement)
                    {
                        p2.Name = string.Format("{0}:{1}",
                            o2.GetType().ToString(),
                            (o2 as DependencyObject).GetValue(FrameworkElement.NameProperty) as String);
                    }
                    else
                    {
                        skipwalk = true;
                        p2.Name = string.Format("{0}:{1}",
                             o2.GetType().ToString(),
                            o2.ToString());
                    }
                    if (!skipwalk)
                        VisualWalk (o2, p2);
                    p.Children.Add(p2);
                }
                if (itemsinlist == 0)
                {
                    p.Children.Add(new NamedElement() { Name = o.GetType().ToString() });
                }
            }
            else
            {
                p.Children.Add(new NamedElement() { Name = o.GetType().ToString() });
            }
        } 
    }     
}
